package database

import (
	"context"
	"fmt"
	"log"
	"time"

	"gitee.com/wangshh_123/cross-pay-go/src/config"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

// MongoDBClient 是全局的 MongoDB 客户端实例
var MongoDBClient *mongo.Client

// InitMongoDB 初始化 MongoDB 连接
func InitMongoDB() error {
	// 检查配置
	if config.GlobalConfig.MongoDB.Host == "" {
		return fmt.Errorf("mongodb host is empty")
	}
	if config.GlobalConfig.MongoDB.Port == "" {
		return fmt.Errorf("mongodb port is empty")
	}

	// 构建 MongoDB 连接URI
	uri := fmt.Sprintf("mongodb://%s:%s", config.GlobalConfig.MongoDB.Host, config.GlobalConfig.MongoDB.Port)

	// 如果有用户名和密码，使用认证
	if config.GlobalConfig.MongoDB.Username != "" && config.GlobalConfig.MongoDB.Password != "" {
		uri = fmt.Sprintf("mongodb://%s:%s@%s:%s/%s?authSource=%s",
			config.GlobalConfig.MongoDB.Username,
			config.GlobalConfig.MongoDB.Password,
			config.GlobalConfig.MongoDB.Host,
			config.GlobalConfig.MongoDB.Port,
			config.GlobalConfig.MongoDB.Database,
			config.GlobalConfig.MongoDB.AuthSource,
		)
	}

	log.Printf("Attempting to connect to MongoDB at %s", uri)

	// 配置客户端选项
	clientOptions := options.Client().ApplyURI(uri)

	// 设置连接池选项
	clientOptions.SetMaxPoolSize(config.GlobalConfig.MongoDB.MaxPoolSize)
	clientOptions.SetMinPoolSize(config.GlobalConfig.MongoDB.MinPoolSize)
	clientOptions.SetMaxConnIdleTime(time.Duration(config.GlobalConfig.MongoDB.MaxIdleTime) * time.Second)
	clientOptions.SetConnectTimeout(time.Duration(config.GlobalConfig.MongoDB.ConnectTimeout) * time.Second)
	clientOptions.SetSocketTimeout(time.Duration(config.GlobalConfig.MongoDB.SocketTimeout) * time.Second)

	// 创建客户端
	client, err := mongo.NewClient(clientOptions)
	if err != nil {
		return fmt.Errorf("failed to create MongoDB client: %v", err)
	}

	// 连接到 MongoDB
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	if err := client.Connect(ctx); err != nil {
		return fmt.Errorf("failed to connect to MongoDB: %v", err)
	}

	// 测试连接
	if err := client.Ping(ctx, nil); err != nil {
		return fmt.Errorf("failed to ping MongoDB: %v", err)
	}

	MongoDBClient = client
	log.Printf("Successfully connected to MongoDB at %s:%s", config.GlobalConfig.MongoDB.Host, config.GlobalConfig.MongoDB.Port)
	return nil
}

// CloseMongoDB 关闭 MongoDB 连接
func CloseMongoDB() error {
	if MongoDBClient != nil {
		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
		defer cancel()
		return MongoDBClient.Disconnect(ctx)
	}
	return nil
}

// GetMongoDBDatabase 获取 MongoDB 数据库实例
func GetMongoDBDatabase() *mongo.Database {
	if MongoDBClient != nil {
		return MongoDBClient.Database(config.GlobalConfig.MongoDB.Database)
	}
	return nil
}

// GetMongoDBCollection 获取 MongoDB 集合实例
func GetMongoDBCollection(collectionName string) *mongo.Collection {
	db := GetMongoDBDatabase()
	if db != nil {
		return db.Collection(collectionName)
	}
	return nil
}
